﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SIGEB.Prototipo.Control;
using SIGEB.Modelo.moduloPerfiles;
using SIGEB.Modelo.moduloUsuarios;
using SIGEB.Modelo.moduloGrupo;
using SIGEB.Modelo;
using SIGEB.Prototipo.Vista.moduloUsuarios;

namespace SIGEB.Prototipo.Vista.moduloEstadisticas
{
    public partial class frm_Estadisticas : frm_ModuloBase
    {
        #region CONSTRUCTORES

        public frm_Estadisticas()
        {
            InitializeComponent();
        }

        public frm_Estadisticas(controlPrincipal cp):base(cp)
        {
            InitializeComponent();
            asignarUI(this.Controls);
            datosActuales = new LinkedList<grupo>();
            datosActualesUsuarios = new LinkedList<usuario>();
            cargarDatos();
            cargarDatosUsuarios();
            dtp_desde.Value = DateTime.Today.AddDays(-1);
            dtp_hasta.Value = DateTime.Today;
        }

        #endregion

        #region MÉTODOS
        
        public override void actualizar(object referencia, bibliotecaObservador.EventoActualizacion e)
        {
            int numConjunto = (int)referencia;
            if (numConjunto == conjuntoBase.CONJGRUPOS)
            {
                cargarDatos();
                asignarPermisos();
            }
            if (numConjunto == conjuntoBase.CONJUSUARIOS)
            {
                cargarDatosUsuarios();
            }
        }

        private void cargarDatos()
        {
            datosActuales = cp.ctrlEstadisticas.obtenerGrupos();
            if(datosActuales != null && datosActuales.Count > 0)
                llenarListBoxGrupos(datosActuales);
        }

        private void cargarDatosUsuarios()
        {
            datosActualesUsuarios = cp.ctrlEstadisticas.obtenerUsuarios();
        }

        public override void hacerVisible(object[] arg)
        {
            base.hacerVisible(arg);
            asignarPermisos();
            predeterminarTodo();
        }

        private void asignarPermisos()
        {
            cmb_tipoFrecuencia.Enabled = false;
            cmb_tipoFrecuencia.Items.Clear();
            if (cp.usuarioActualPuede(acciones.ESTADISTICA_TOD))
            {
                cmb_tipoFrecuencia.Enabled = true;
                cmb_tipoFrecuencia.Items.AddRange(new object[]{"Frecuencia de Préstamos - Todos los Usuarios",
                                                                "Frecuencia de Préstamos - Un solo Usuario",
                                                                "Frecuencia de Préstamos - Por Grupo",
                                                                "Frecuencia de Ingreso de Documentos"});
            }
            else if (cp.usuarioActualPuede(acciones.ESTADISTICA_ACT))
            {
                cmb_tipoFrecuencia.Enabled = true;
                cmb_tipoFrecuencia.Items.AddRange(new object[] { "Frecuencia de Préstamos - Un solo Usuario" });
            }
        }

        private void predeterminarTodo()
        {
            default_gbx_identificacionUsuario();
            default_gbx_area();
            default_gbx_rango();
        }

        private void frec_prestamos_Usuarios()
        {
            modo = 1;
            predeterminarTodo();
            gbx_rango.Enabled = true;
        }

        private void frec_prestamos_Usuario()
        {
            modo = 2;
            predeterminarTodo();
            gbx_identificacionUsuario.Enabled = true;
            gbx_rango.Enabled = true;
        }

        private void frec_prestamos_Area()
        {
            modo = 3;
            predeterminarTodo();
            gbx_area.Enabled = true;
            gbx_rango.Enabled = true;
        }

        private void frec_ingreso_Documentos()
        {
            modo = 4;
            predeterminarTodo();
            gbx_rango.Enabled = true;
        }

        private void default_gbx_rango()
        {
            dtp_desde.Value = new DateTime(2010, 1, 1);
            dtp_hasta.Value = DateTime.Today;

            cmb_tiempo.Items.AddRange(new object[]{
                                                "Años",
                                                "Meses",
                                                "Semanas",
                                                "Días"
                                                });

            txb_tiempo.Text = string.Empty;
            lbl_tiempo.Text = "Días";

            agregarValoresCombo();
            gbx_rango.Enabled = false;
        }

        private void default_gbx_area()
        {
            lsb_grupos.ClearSelected();
            gbx_area.Enabled = false;
        }

        private void default_gbx_identificacionUsuario()
        {
            txb_identificacionUsuario.Text = string.Empty;
            gbx_identificacionUsuario.Enabled = false;
        }

        private void llenarListBoxGrupos(LinkedList<grupo> lista)
        {
            if (lista != null && lista.Count > 0)
            {
                lsb_grupos.Items.Clear();
                foreach (grupo g in lista)
                {
                    lsb_grupos.Items.AddRange(new object[] { g.nombre });
                }
            }
        }

        private void mostrarGrafico(int dias, int medida)
        {
            LinkedList<SIGEB.Modelo.moduloEstadisticas.datoEstadistico> datos = new LinkedList<Modelo.moduloEstadisticas.datoEstadistico>();

            if (modo.Equals(1))
            {
                datos = cp.ctrlEstadisticas.usoBiblioteca(dtp_desde.Value, dtp_hasta.Value, dias, medida);
            }
            else if (modo.Equals(2))
            {
                if (!txb_identificacionUsuario.Text.Equals(string.Empty))
                    datos = cp.ctrlEstadisticas.usoBibliotecaUsuario(dtp_desde.Value, dtp_hasta.Value, dias, txb_identificacionUsuario.Text, medida);
                else
                {
                    setError(btn_identificacionUsuario, "Debe seleccionar un usuario antes de continuar.");
                    return;
                }
            }
            else if(modo.Equals(3))
            {
                if (lsb_grupos.SelectedItems.Count <= 0)
                {
                    setError(lsb_grupos, "Debe seleccionar al menos un grupo antes de continuar.");
                    return;
                }
                else if (lsb_grupos.SelectedItems.Count.Equals(1))
                {
                    datos = cp.ctrlEstadisticas.usoBibliotecaGrupo(dtp_desde.Value, dtp_hasta.Value, dias, lsb_grupos.SelectedItem as String, medida);
                }
                else
                {
                    LinkedList<string> idGrupos = new LinkedList<string>();
                    string itm = string.Empty;
                    foreach(grupo g in datosActuales)
                    {
                        foreach (Object selecteditem in lsb_grupos.SelectedItems)
                        {
                            itm = selecteditem as String;
                            if (g.nombre.Equals(itm))
                            {
                                idGrupos.AddLast(g.codGrupo);
                            }
                        }
                    }
                    datos = cp.ctrlEstadisticas.usoPorGrupos(dtp_desde.Value, dtp_hasta.Value, dias, idGrupos, medida);
                    idGrupos.Clear();
                }
            }
            else if(modo.Equals(4))
            {
                datos = cp.ctrlEstadisticas.ingresoDocumentos(dtp_desde.Value, dtp_hasta.Value, dias, medida);
            }

            object[] param = new object[4];
            string titulo, lbl_ejeX, lbl_ejeY;

            titulo = "SIGEB - Sin Titulo";
            lbl_ejeX = "Rangos de Fechas";
            lbl_ejeY = "Cantidad de Préstamos";

            if (modo.Equals(1))
            {
                titulo = "Cantidad de Préstamos de todos los Usuarios Registrados.\nDesde el " + dtp_desde.Value.Date.ToShortDateString() + ", hasta el " + dtp_hasta.Value.Date.ToShortDateString();
            }
            else if (modo.Equals(2))
            {
                titulo = "Cantidad de Préstamos realizados por el Usuario " + txb_identificacionUsuario.Text + ".\nDesde el " + dtp_desde.Value.Date.ToShortDateString() + ", hasta el " + dtp_hasta.Value.Date.ToShortDateString();
            }
            else if (modo.Equals(3))
            {
                string grupos = string.Empty;
                string item = string.Empty;
                int i = 1;
                foreach (Object selecteditem in lsb_grupos.SelectedItems)
                {
                    item = selecteditem as String;
                    if (i < lsb_grupos.SelectedItems.Count)
                    {
                        grupos += item + ", ";
                    }
                    else
                    {
                        grupos += item;
                    }
                    i++;
                }

                titulo = lsb_grupos.SelectedItems.Count > 1 ? "Cantidad de Préstamos realizados por las Áreas de " + grupos + ".\nDesde el " + dtp_desde.Value.Date.ToShortDateString() + ", hasta el " + dtp_hasta.Value.Date.ToShortDateString() :
                    "Cantidad de Préstamos realizados por el Área de " + grupos + ".\nDesde el " + dtp_desde.Value.Date.ToShortDateString() + ", hasta el " + dtp_hasta.Value.Date.ToShortDateString();
            }
            else if (modo.Equals(4))
            {
                titulo = "Número de ingresos de Documentos Nuevos.\nDesde el " + dtp_desde.Value.Date.ToShortDateString() + ", hasta el " + dtp_hasta.Value.Date.ToShortDateString();
                lbl_ejeY = "Cantidad de Ingresos (Registros)";
            }

            param[0] = titulo;
            param[1] = lbl_ejeX;
            param[2] = lbl_ejeY;
            param[3] = datos;

            cp.abrirVentana(this, controlPrincipal.VENTANA_REPORTE_ESTADISTICO, param);
            cmb_tipoFrecuencia.SelectedIndex = -1;
            predeterminarTodo();
            modo = -1;
        }

        #endregion

        #region EVENTOS

        private void lsb_grupos_SelectedIndexChanged(object sender, EventArgs e)
        {
            borrarError(lsb_grupos);
        }

        private void cmb_tiempo_SelectedIndexChanged(object sender, EventArgs e)
        {
            borrarError(cmb_tiempo);

            if(cmb_tiempo.Text.Equals("Años"))
            {
                txb_tiempo.Text = string.Empty;
                lbl_tiempo.Text = "Años";
            }
            else if (cmb_tiempo.Text.Equals("Meses"))
            {
                txb_tiempo.Text = string.Empty;
                lbl_tiempo.Text = "Meses";
            }
            else if (cmb_tiempo.Text.Equals("Semanas"))
            {
                txb_tiempo.Text = string.Empty;
                lbl_tiempo.Text = "Semanas";
            }
            else if (cmb_tiempo.Text.Equals("Días"))
            {
                txb_tiempo.Text = string.Empty;
                lbl_tiempo.Text = "Días";
            }
        }

        private void cmb_tipoFrecuencia_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(cmb_tipoFrecuencia.Items.Count.Equals(1))
            {
                frec_prestamos_Usuario();
            }
            else if (cmb_tipoFrecuencia.Items.Count.Equals(4))
            {
                switch(cmb_tipoFrecuencia.SelectedIndex)
                {
                    case 0: frec_prestamos_Usuarios(); break;
                    case 1: frec_prestamos_Usuario(); break;
                    case 2: frec_prestamos_Area(); break;
                    case 3: frec_ingreso_Documentos(); break;
                }
            }
        }

        private void frm_Estadisticas_Load(object sender, EventArgs e)
        {
            predeterminarTodo();
        }

        private void btn_generarReporte_Click(object sender, EventArgs e)
        {
            if(cmb_tiempo.SelectedIndex.Equals(-1))
            {
                setError(cmb_tiempo, "Seleccione la división de rangos a utilizar.");
                return;
            }
            if (!(txb_tiempo.Text.Equals(string.Empty) || int.Parse(txb_tiempo.Text).Equals(0)))
            {
                TimeSpan a = dtp_hasta.Value - dtp_desde.Value;
                if (cmb_tiempo.Text.Equals("Años"))
                {
                    if (int.Parse(txb_tiempo.Text) * 12 * 4 * 7 > a.Days)
                    {
                        setError(txb_tiempo, "El rango ingresado debe ser menor o igual al intervalo de fechas seleccionado.");
                    }
                    else
                    {
                        mostrarGrafico(int.Parse(txb_tiempo.Text), controlEstadisticas.ANIO);
                    }
                }
                else if (cmb_tiempo.Text.Equals("Meses"))
                {
                    if (int.Parse(txb_tiempo.Text) * 4 * 7 > a.Days)
                    {
                        setError(txb_tiempo, "El rango ingresado debe ser menor o igual al intervalo de fechas seleccionado.");
                    }
                    else
                    {
                        mostrarGrafico(int.Parse(txb_tiempo.Text), controlEstadisticas.MES);
                    }
                }
                else if (cmb_tiempo.Text.Equals("Semanas"))
                {
                    if (int.Parse(txb_tiempo.Text) * 7 > a.Days)
                    {
                        setError(txb_tiempo, "El rango ingresado debe ser menor o igual al intervalo de fechas seleccionado.");
                    }
                    else
                    {
                        mostrarGrafico(int.Parse(txb_tiempo.Text), controlEstadisticas.SEMANAS);
                    }
                }
                else if (cmb_tiempo.Text.Equals("Días"))
                {
                    if (int.Parse(txb_tiempo.Text) > a.Days)
                    {
                        setError(txb_tiempo, "El rango ingresado debe ser menor o igual al intervalo de fechas seleccionado.");
                    }
                    else
                    {
                        mostrarGrafico(int.Parse(txb_tiempo.Text), controlEstadisticas.DIAS);
                    }                    
                }
            }
            else
            {
                setError(txb_tiempo, "Ingrese un valor de división de rango.");
                return;
            }
        }

        private void dtp_desde_ValueChanged(object sender, EventArgs e)
        {
            borrarError(dtp_desde);
            if(dtp_desde.Value >= dtp_hasta.Value)
            {
                setError(dtp_desde, "La fecha inicial del rango debe ser menor que la fecha final.");
                dtp_desde.Value = DateTime.Today.AddDays(-7);
                return;
            }
            DateTime dminimo = new DateTime(2003, 1, 1);
            if (dtp_desde.Value < dminimo)
            {
                dtp_desde.Value = DateTime.Today.AddDays(-7);
            }
            else
            {
                agregarValoresCombo();
            }
        }

        private void dtp_hasta_ValueChanged(object sender, EventArgs e)
        {
            borrarError(dtp_hasta);
            if (dtp_hasta.Value <= dtp_desde.Value)
            {
                setError(dtp_hasta, "La fecha final del rango debe ser mayor que la fecha inicial.");
                dtp_hasta.Value = DateTime.Today;
                return;
            }
            if (dtp_hasta.Value > DateTime.Today)
            {
                dtp_hasta.Value = DateTime.Today;
            }
            else
            {
                agregarValoresCombo();
            }
        }

        private void agregarValoresCombo()
        {
            TimeSpan a = dtp_hasta.Value - dtp_desde.Value;
            cmb_tiempo.Items.Clear();
            if (a.Days > 365)
            {
                cmb_tiempo.Items.Add("Años");
            }
            if (a.Days > 30)
            {
                cmb_tiempo.Items.Add("Meses");
            }
            if (a.Days > 7)
            {
                cmb_tiempo.Items.Add("Semanas");
            }
            if (a.Days > 1)
            {
                cmb_tiempo.Items.Add("Días");
            }
        }

        private void txb_identificacionUsuario_TextChanged(object sender, EventArgs e)
        {
            borrarError(btn_identificacionUsuario);
            if (!(txb_identificacionUsuario.Text.Equals(string.Empty)))
            {
                gbx_rango.Visible = true;
            }
        }

        private void txb_tiempo_TextChanged(object sender, EventArgs e)
        {
            borrarError(txb_tiempo);
        }

        private void btn_identificacionUsuario_Click(object sender, EventArgs e)
        {
            objetoReturn a = new objetoReturn();
            new busquedaUsuario(datosActualesUsuarios , a).ShowDialog();
            txb_identificacionUsuario.Text = a.objeto;
        }

        private void txb_tiempo_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (Char.IsNumber(e.KeyChar))
            {
                e.Handled = false;
            }
            if (Char.IsLetter(e.KeyChar) || Char.IsSeparator(e.KeyChar) || 
                Char.IsPunctuation(e.KeyChar) || Char.IsSymbol(e.KeyChar))
            {
                e.Handled = true;
            }
        }

        #endregion

        #region ATRIBUTOS

        private int modo = -1;
        private LinkedList<grupo> datosActuales;
        private LinkedList<usuario> datosActualesUsuarios;

        #endregion
    }
}
